feat(vpto): add sequential soft post-update analysis - #1018
Conversation
875a554 to
5baca6d
Compare
1d24871 to
3e10509
Compare
mouliangyu
left a comment
There was a problem hiding this comment.
整体方向上,在 VPTO/MLIR 层识别 post-update 是合理的;但当前 sequential path 还需要补齐收益判定,并分开地址数学语义与硬件窄 stride 编码。具体见两条 inline comment。
|
|
||
| static bool validateSequentialRun(SequentialRun &run, | ||
| DominanceInfo &dominance) { | ||
| if (run.candidates.size() < 3) |
There was a problem hiding this comment.
这里似乎把‘能够改写为 post-update’直接当成了‘值得改写’,但目前没有看到 sequential path 的 profitability 判断。
例如本 PR 的 sequential_constant:
vlds %base[0]
vlds %base[64]
vlds %base[128]未开启该优化时,LLVM IR 已经是三条彼此独立的访存:
vlds(base, 0)
vlds(base, 256)
vlds(base, 512)这里没有额外地址计算需要消除。改写后则变成:
v0, p1 = vlds.post(base, 256)
v1, p2 = vlds.post(p1, 256)
v2, p3 = vlds.post(p2, 256)不仅没有减少地址计算,还在原本独立的访存之间增加了 pointer dependency;最后一条产生的 p3 也没有被使用。
因此仅用 run length >= 3 作为改写条件似乎不够。是否应该只处理能够实际消除动态 addptr/offset 计算的序列,或者先基于汇编与性能数据建立 cost model?另外,对于长度为 N 的链,通常只需要前 N-1 条使用 post-update,最后一条可以使用当前 pointer 加零 offset 的普通形式。
| return e->leaf; | ||
| case StrideExpr::Kind::Cast: { | ||
| Type inputType = e->castOp->getOperand(0).getType(); | ||
| if (wantType == inputType) |
There was a problem hiding this comment.
这里直接把规范化后的地址差表达式按目标 operand 类型物化,会把‘宽类型地址语义’和‘硬件窄 stride 编码’混在一起,可能改变原程序语义。
例如 %k: i16,三个 vsstb 的 base 分别为:
%k_idx = arith.index_castui %k : i16 to index
%off1 = arith.muli %k_idx, %c16 : index
%off2 = arith.muli %k_idx, %c32 : index
base, addptr(base, 16 * zext(k)), addptr(base, 32 * zext(k))对 f32 而言,相邻地址差是 2 * zext(k) 个 32B block。当前实现会消除 index_castui,生成:
%step = arith.muli %k, %c2_i16 : i16当 %k = 40000 时,原始地址差是 80000 blocks,但新表达式在 i16 中先回绕成 14464,地址序列已经不同。
我觉得这里不只是缺少一个常量范围检查。地址差分析应该始终在 index/宽整数的数学域中完成;确认完整表达式能够精确编码到该 op 的硬件 stride 类型后,才能在最后一步生成 i16 operand。无法证明运行时范围时应保守放弃,而不是通过去掉 cast 将运算下沉到 i16。
Summary
Implement Step 3 of
VPTOSoftPostUpdatefor issue #941 : convert fixed-stride memory accesses within a single block into chained post-update operations.Key changes
Add a second analysis phase after loop-path rewriting.
scf.forrewrites.scf.forbodies, and nested regions such asscf.if.Normalize addresses as
(rootBase, baseOffset)throughpto.addptrchains.Reuse the loop-path infrastructure for:
Support constant and symbolic affine strides, including:
8 * kfor f32vsstb.Group candidates by
(op type, rootBase)and detect deterministic,non-overlapping maximal arithmetic runs.
Analyze all accepted runs before materialization, then rewrite operations in
original program order while maintaining an independent pointer chain per run.
Update the pass description and Step 3 design documentation.
Test coverage
Added 8 sequential-path lit test files containing 22 focused scenarios, including:
pto.addptrnormalization;scf.forbody fallback and nestedscf.ifblocks;vlds,vsts, andvsstbpointer chaining;vsstbrepeat stride;Validation
Commands: